<template>
  <div class="theme-container">
    <!-- 设置单独颜色配置框 -->
    <a-tooltip v-if="showColorSetting" placement="top" :mouse-enter-delay="0.5">
      <template slot="title">
        <span>更改颜色项</span>
      </template>
      <a-dropdown :trigger="['click']" overlay-class-name="color-value-map">
        <a-icon-font class="color-set" type="icongenggaiyansexiang" />
        <!-- 下拉菜单内容 -->
        <a-menu slot="overlay">
          <a-menu-item v-for="(item, index) in colorLabelMapping" :key="index">
            <!-- 颜色拾色器 popup -->
            <a-popover
              trigger="click"
              placement="left"
              :overlay-class-name="'sys-popover-color-picker'"
              :visible="colorPopoverVisible && currentIndex === index"
              :arrow-point-at-center="true"
            >
              <div class="color-map-item" @click.stop="openColorPopover(index)">
                <div
                  class="color-container"
                  :class="{ 'select-color': currentIndex === index }"
                >
                  <span
                    class="single-color"
                    :style="{ backgroundColor: item.color }"
                  >
                  </span>
                </div>
                <!-- 颜色对应的图例名称 -->
                <span class="label-name">
                  {{ item.name }}
                </span>
              </div>
              <!-- 颜色拾色器 -->
              <div slot="content" @click.stop>
                <sketch
                  v-model="copyColorLabelMap[index].color"
                  :preset-colors="uniqueValue"
                />
                <div class="cancel-confirm">
                  <a-button
                    key="back"
                    size="small"
                    class="cancel-button"
                    @click="colorPopoverVisible = false"
                  >
                    取消
                  </a-button>
                  <a-button
                    key="submit"
                    type="primary"
                    size="small"
                    @click="globalColorHandleOk(index)"
                  >
                    确定
                  </a-button>
                </div>
              </div>
            </a-popover>
          </a-menu-item>
        </a-menu>
      </a-dropdown>
    </a-tooltip>
    <!-- 常规主题下拉框 -->
    <a-dropdown :trigger="['click']" overlay-class-name="theme-menu">
      <a-button
        class="ant-kg-appl-dropdown-link"
        @click="onMenuExpand"
        @blur="onMenuBlur"
      >
        <span class="menu-item-row">
          <span
            v-for="(color, i) in parseValue.slice(0, 12)"
            :key="`color-${i}`"
            class="theme-color"
            :style="{ backgroundColor: color }"
          >
          </span>
        </span>
        <!-- 主题色名称 -->
        <span class="color-name">
          {{ colorNameMapping(parseValue) }}
        </span>
        <span class="color-picker-arrow">
          <a-icon
            id="color-menu-arrow"
            type="down"
            :class="!shouldExpand ? 'toggle-up' : 'toggle-down'"
          />
        </span>
      </a-button>
      <template #overlay>
        <a-menu slot="overlay" @click="onThemeColorChange">
          <a-menu-item
            v-for="item in renderOptions"
            :key="item.label"
            :class="{
              active: item.value.join(',') === parseValue.join(','),
              'theme-menu-item': true,
            }"
          >
            <a href="javascript:;">
              <span class="menu-item-row">
                <span
                  v-for="(color, i) in item.value"
                  :key="`color-${i}`"
                  class="theme-color"
                  :style="{ backgroundColor: color }"
                >
                </span>
              </span>
              <!-- 主题色名称 -->
              <span class="color-name">
                {{ item.label }}
              </span>
            </a>
          </a-menu-item>
        </a-menu>
      </template>
    </a-dropdown>
  </div>
</template>

<script lang="ts">
/* eslint-disabled */
import { Vue, Prop, Component, Watch } from 'vue-property-decorator'
import { THEME_COLORS } from '@/components/common/VisualizationComp/constants'
import { Sketch } from 'vue-color'
import { cloneDeep, isEqual } from 'lodash'

@Component({
  components: {
    Sketch,
  },
})
export default class ThemeColorPicker extends Vue {
  @Prop({ default: () => [] }) value!: string[] // 必须, 接受form的值
  @Prop({ default: 'small' }) size!: string
  @Prop() infoData?: any //  chart 配置信息
  @Prop() options!: Array<{ label: string; type: string; value: string[] }>

  public shouldExpand: boolean = true
  public colorPopoverVisible: boolean = false // label颜色设置popup
  public currentIndex: number = -1 //  初始颜色列表顺序值
  public showColorSetting: boolean = false //  根据传入的表格类型是否显示 单独颜色配置btn
  public colorLabelMapping: any = [] //  存储颜色label映射对象列表
  public copyColorLabelMap: any = [] //  colorLabelMapping的复制，暂存修改

  private get renderOptions() {
    //  barChart type, 返回所有主题色
    if (this.infoData.chartType === 'barChart') {
      return this.options
    }
    //  非barChart type, 返回非纯色 主题
    return this.options.filter((option: any) => {
      return !option.forBarChart
    })
  }
  /** new color picker start */

  //  获取主题色列表去重后的颜色列表, 用于拾色器颜色列表
  private get uniqueValue() {
    return [...new Set(this.parseValue)]
  }
  //  返回回显的色值列表
  private get parseValue(): any {
    //  纯barChart, 除diffBar 外
    if (this.infoData.chartType === 'barChart' && !Array.isArray(this.value)) {
      return Object.values(this.value)
    }
    return this.value
  }

  //  允许开启颜色配置的图表列表
  public colorSetEnableList = [
    'barChart', //  包含diffBar
    'groupBarChart',
    'stackBarChart',
    'pieChart',
    'donutChart',
    'areaChart',
    'lineChart',
  ]

  @Watch('infoData', { immediate: true, deep: true })
  handleInfoData(newValue: any) {
    if (newValue) {
      //  当前图表类型是否需要显示颜色配置
      this.showColorSetting = this.colorSetEnableList.includes(
        newValue.chartType
      )
      if (this.showColorSetting) {
        this.colorLabelMapping = []
        //  为各个label 赋值颜色
        newValue.labelList.forEach((item: any, index: number) => {
          this.colorLabelMapping.push({
            name: item,
            color: this.parseValue[index % this.parseValue.length],
          })
        })
        //  复制一份映射
        this.copyColorLabelMap = cloneDeep(this.colorLabelMapping)
      }
    }
  }
  /**
   * 获取主题色名称映射
   * @param colorValue
   */
  private colorNameMapping(colorValue: any) {
    const target = THEME_COLORS.find((item: any) => {
      return isEqual(item.value, colorValue.slice(0, item.value.length))
    })

    return target?.label ?? '自定义'
  }

  /**
   * 打开颜色设置popup
   * @param index 打开的拾色器popup 序号
   */
  public openColorPopover(index: number) {
    this.currentIndex = index
    this.colorPopoverVisible = !this.colorPopoverVisible
    if (!this.colorPopoverVisible) {
      //  重新赋值
      this.copyColorLabelMap[index].color = this.colorLabelMapping[index].color
    }
  }

  /**
   * 全局颜色设定 确定
   * @param index 确认的拾色器popup 序号
   */
  public globalColorHandleOk(index: number) {
    this.colorPopoverVisible = false
    //  没有改动色值
    if (
      this.copyColorLabelMap[index].color ===
      this.colorLabelMapping[index].color
    ) {
      return
    }
    //  覆盖原值
    this.colorLabelMapping[index].color =
      this.copyColorLabelMap[index].color.hex
    //  barChart colors用对象的写法
    if (this.infoData.chartType === 'barChart') {
      const color: any = {}

      this.colorLabelMapping.forEach((item: any) => {
        color[item.name] = item.color
      })
      //  如果设置的label颜色数量 少于 主题色 数量时，填充后续的颜色
      if (Object.keys(color).length < this.parseValue.length) {
        for (
          let i = Object.keys(color).length;
          i < this.parseValue.length;
          i += 1
        ) {
          color[`add_${i}`] = this.parseValue[i] //  为了回显正常， 添加多余的key-value
        }
      }
      this.$emit('change', color) // emit change 事件，把改变的value传出去
    } else {
      //  其余类型colors用数组的写法
      const color: string[] = []
      this.colorLabelMapping.forEach((item: any) => color.push(item.color))

      //  如果设置的label颜色数量 少于 主题色 数量时，填充后续的颜色
      if (color.length < this.parseValue.length) {
        for (let i = color.length; i < this.parseValue.length; i += 1) {
          color.push(this.parseValue[i])
        }
      }
      this.$emit('change', color) // emit change 事件，把改变的value传出去
    }
  }
  /** new color picker end */

  private onMenuExpand(event: any) {
    event.preventDefault()
    this.shouldExpand = !this.shouldExpand
  }

  private onMenuBlur() {
    if (this.shouldExpand === false) {
      this.shouldExpand = !this.shouldExpand
    }
  }

  private onThemeColorChange({ key }: { key: string }) {
    const color = this.options.filter((item) => item.label === key)[0].value

    if (this.infoData.chartType === 'barChart') {
      const result: any = {}
      this.colorLabelMapping.forEach((item: any, index: number) => {
        result[item.name] = color[index % color.length]
      })
      //  如果设置的label颜色数量 少于 主题色 数量时，填充后续的颜色
      if (Object.keys(result).length < color.length) {
        for (let i = Object.keys(result).length; i < color.length; i += 1) {
          result[`add_${i}`] = color[i]
        }
      }

      this.$emit('change', result) // emit change 事件，把改变的value传出去
    } else {
      this.$emit('change', color) // emit change 事件，把改变的value传出去
    }
  }
}
</script>

<style lang="less" scoped>
.theme-container {
  align-items: center;
  display: flex;
  height: 40px;
}

.theme-menu {
  .theme-menu-item {
    a {
      align-items: center;
      display: flex;
      margin: -2px;
      padding: 2px;
    }

    &.active {
      opacity: 1;

      a {
        border: 1px solid #6973ff;
      }
    }
  }

  .menu-item-row {
    display: flex;
    flex-wrap: wrap;
    height: 16px;
    margin-right: 8px;
    max-width: 48px;
  }

  .theme-color {
    display: inline-block;
    height: 8px;
    vertical-align: top;
    width: 8px;
  }

  .ant-kg-appl-dropdown-menu {
    max-height: 260px;
    overflow-y: scroll;

    &::-webkit-scrollbar {
      height: 6px;
      visibility: hidden;
      width: 5px;
    }

    &::-webkit-scrollbar-thumb {
      background: rgba(144, 147, 153, 0.5);
      border-radius: 6px;
      visibility: hidden;
    }

    &:hover {
      &::-webkit-scrollbar {
        visibility: visible;
      }

      &::-webkit-scrollbar-thumb {
        visibility: visible;
      }
    }

    &::-webkit-scrollbar-track {
      background: #fff;
      border-radius: 5px;
    }
  }
}

.color-value-map {
  .color-map-item {
    align-items: center;
    display: flex;

    .color-container {
      border: 1px solid rgba(217, 217, 217, 1);
      border-radius: 2px;
      height: 14px;
      padding: 0.5px;
      width: 14px;

      .single-color {
        display: inline-block;
        height: 11px;
        vertical-align: top;
        width: 11px;
      }
    }

    .color-container.select-color {
      border: 1px solid rgba(103, 113, 255, 1);
    }

    .label-name {
      margin-left: 8px;
      max-width: 90px;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }

  .ant-kg-appl-dropdown-menu {
    max-height: 164px;
    overflow-y: scroll;
    width: 130px;

    &::-webkit-scrollbar {
      height: 6px;
      visibility: hidden;
      width: 5px;
    }

    &::-webkit-scrollbar-thumb {
      background: rgba(144, 147, 153, 0.5);
      border-radius: 6px;
      visibility: hidden;
    }

    &:hover {
      &::-webkit-scrollbar {
        visibility: visible;
      }

      &::-webkit-scrollbar-thumb {
        visibility: visible;
      }
    }

    &::-webkit-scrollbar-track {
      background: #fff;
      border-radius: 5px;
    }

    .ant-kg-appl-dropdown-menu-item {
      padding-right: 0;
    }
  }
}

.color-set {
  cursor: pointer;
  height: 16px;
  margin-right: 6px;
  width: 16px;

  &:hover {
    color: #6973ff;
  }
}

.ant-kg-appl-dropdown-link {
  align-items: center;
  display: flex;
  padding: 0 5px;

  .color-picker-arrow {
    color: rgba(0, 0, 0, 0.25);
    font-size: 12px;
    padding-left: 5px;

    .toggle-down {
      transform: rotate(0deg);
      transition: transform 0.3s linear;
    }

    .toggle-up {
      transform: rotate(180deg);
      transition: transform 0.3s linear;
    }
  }

  .theme-color {
    display: inline-block;
    height: 8px;
    vertical-align: middle;
    width: 8px;
  }

  .menu-item-row {
    display: flex;
    flex-wrap: wrap;
    height: 16px;
    margin-right: 8px;
    max-width: 48px;
  }
}
</style>

<style lang="less">
.sys-popover-color-picker {
  border-radius: 4px;

  .ant-kg-appl-popover-content {
    width: 220px;

    .ant-kg-appl-popover-inner {
      box-shadow: 0 0 8px #c5c9ff;

      .ant-kg-appl-popover-inner-content {
        padding: 0;
      }
    }
  }

  .vc-sketch {
    border-radius: 4px 4px 0 0;
    box-shadow: none;
  }

  .cancel-confirm {
    display: flex;
    justify-content: flex-end;
    padding: 6px 12px;

    .cancel-button {
      margin-right: 12px;
    }
  }
}
</style>
